package com.wiscamp.ninechapters.panels.application.services;

import com.wiscamp.ninechapters.panels.application.assemblers.MenuAssembler;
import com.wiscamp.ninechapters.panels.application.command.CreateMenuCommand;
import com.wiscamp.ninechapters.panels.application.command.UpdateMenuCommand;
import com.wiscamp.ninechapters.panels.application.vo.MenuVO;
import com.wiscamp.ninechapters.panels.domain.repositories.MenuRepository;
import com.wiscamp.ninechapters.panels.domain.services.MenuService;
import cube.ddd.application.BaseAppService;
import cube.ddd.application.command.DeleteCommand;
import cube.ddd.application.command.DisableCommand;
import cube.ddd.application.command.EnableCommand;
import cube.ddd.aspect.HandleServiceException;
import cube.ddd.common.query.PagedObjects;
import cube.ddd.common.query.PagedQuery;
import cube.ddd.utils.AppServiceUtils;
import jakarta.validation.Valid;
import org.springframework.stereotype.Service;

import java.util.Collection;

@Service
public class MenuAppService extends BaseAppService {


    private final MenuRepository menuRepository;

    private final MenuService menuService;

    public MenuAppService(MenuRepository menuRepository, MenuService menuService) {
        this.menuRepository = menuRepository;
        this.menuService = menuService;
    }

    @HandleServiceException
    public MenuVO getMenu(long menuId) {
        return AppServiceUtils.getById(menuId, menuService::getMenu,
                MenuAssembler.Instance::toMenuVO);
    }

    @HandleServiceException
    public MenuVO getMenuByCode(long appId, String menuCode) {
        return AppServiceUtils.getByIdAndText(appId, menuCode, menuRepository::getMenuByCode,
                MenuAssembler.Instance::toMenuVO);
    }

    @HandleServiceException
    public Collection<MenuVO> getMenusByName(long appId, String menuName) {
        return AppServiceUtils.getListByIdAndText(appId, menuName, menuRepository::getMenusByName,
                MenuAssembler.Instance::toMenuVO);
    }

    @HandleServiceException
    public Collection<MenuVO> getMenusByGroup(long appId, String appGroup) {
        return AppServiceUtils.getListByIdAndText(appId, appGroup, menuRepository::getMenusByGroup,
                MenuAssembler.Instance::toMenuVO);
    }

    @HandleServiceException
    public PagedObjects<MenuVO> getMenusByQuery(PagedQuery pagedQuery) {
        var pagedObjects = menuRepository.getMenusByQuery(pagedQuery);
        return AppServiceUtils.convertPagedObjects(pagedObjects, MenuAssembler.Instance::toMenuVO);
    }

    @HandleServiceException
    public MenuVO createMenu(@Valid CreateMenuCommand command) {
        command.setOperatorId(getCurrentUserId());
        return AppServiceUtils.createOrUpdateBy(command, command.getOperatorId(), menuService::createMenu,
                MenuAssembler.Instance::toMenuVO, MenuAssembler.Instance::fromCreateCommand);
    }

    @HandleServiceException
    public MenuVO updateMenu(@Valid UpdateMenuCommand command) {
        command.setOperatorId(getCurrentUserId());
        return AppServiceUtils.createOrUpdateBy(command, command.getOperatorId(), menuService::updateMenu,
                MenuAssembler.Instance::toMenuVO, MenuAssembler.Instance::fromUpdateCommand);
    }

    @HandleServiceException
    public boolean deleteMenu(@Valid DeleteCommand command) {
        command.setOperatorId(getCurrentUserId());
        return AppServiceUtils.delete(command.getId(), command.getOperatorId(), menuService::deleteMenu);
    }

    @HandleServiceException
    public boolean enableMenu(@Valid EnableCommand command) {
        command.setOperatorId(getCurrentUserId());
        return AppServiceUtils.enable(command.getId(), command.getOperatorId(), menuService::enableMenu);
    }

    @HandleServiceException
    public boolean disableMenu(@Valid DisableCommand command) {
        command.setOperatorId(getCurrentUserId());
        return AppServiceUtils.disable(command.getId(), command.getOperatorId(), menuService::disableMenu);
    }
}
